package com.aner.tester.generator.code;

import com.aner.tester.constant.Constant;
import com.aner.tester.exception.CustomException;
import com.aner.tester.object.ControllerObject;
import org.apache.commons.io.FileUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.slf4j.Logger;
import com.aner.tester.utils.LoggerUtils;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;

/**
 * code generator
 *
 * @author aner
 * @version 1.0
 * @date 2020/12/12 18:53
 */
public class CodeGenerator {

    private Logger logger = LoggerUtils.getLogger(CodeGenerator.class);

    /**
     *  the count of the same controllerTest file
     */
    private static int FILE_COUNT = 2;

    public void generate(List<ControllerObject> controllerObjectList) {

        for(ControllerObject controllerObject : controllerObjectList) {
            String path = doGenerate(controllerObject);
            logger.info("Existing file not overwritten, the generated file is saved {} ", path);
        }
    }
    /**
     * generate code
     *
     * @param controllerObject
     */
    public String doGenerate(ControllerObject controllerObject)
    {

        VelocityFactory.init();
        VelocityContext context = VelocityFactory.prepareContext(controllerObject);

        // get template name
        String template = VelocityFactory.getTemplate();
        // render template
        StringWriter sw = new StringWriter();
        Template tpl = Velocity.getTemplate(template, Constant.UTF_8);
        tpl.merge(context, sw);
        try
        {
            String path = getGenPath(controllerObject);
            FileUtils.writeStringToFile(new File(path), sw.toString(), Constant.UTF_8);
            return path;
        }
        catch (IOException e)
        {
            throw new CustomException(" the generation of controller test file  is error, name of class is ：" + controllerObject.getClassName());
        }
    }

    /**
     * get path
     *
     */
    public static String getGenPath(ControllerObject controllerObject)
    {
        String path =  getRootPath() + "src" +
                "/" + VelocityFactory.getFileName(controllerObject.getPackageName(), controllerObject.getClassName());
        return validPath(path, 1);
    }

    /**
     * get root project path
     * @return
     */
    public static String getRootPath() {
        String classPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
        String rootPath = classPath.substring(0, classPath.indexOf("target"));
        return rootPath;
    }

    public static String validPath(String path, int index) {

        if (index > FILE_COUNT) {
            return path;
        }
        File file = new File(path);
        if (file.exists()) {
            String newName = (index == 1 ? path: path.substring(0, path.length() - 2)) + "." + index;
            return validPath(newName, index + 1);
        } else {
            return path;
        }
    }
}
